home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / BORL_TIP / TI100 / TI229.ASC < prev    next >
Text File  |  1991-09-11  |  9KB  |  331 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  10.   VERSION : ALL
  11.        OS : PC-DOS, MS-DOS
  12.      DATE : August 1, 1986                               PAGE : 1/5
  13.     TITLE : EXECUTE SUBPROCESS CALL
  14.  
  15.  
  16.  
  17.  
  18.   The following example routines are public domain programs that
  19.   have been uploaded to our Forum on CompuServe. As a courtesy to
  20.   our users that do not have immediate access to CompuServe,
  21.   Technical Support distributes these routines free of charge.
  22.  
  23.   However, because these routines are public domain programs, not
  24.   developed by Borland International, we are unable to provide any
  25.   technical support or assistance using these routines. If you need
  26.   assistance using these routines, or are experiencing
  27.   difficulties, we recommend that you log onto CompuServe and
  28.   request assistance from the Forum members that developed these
  29.   routines.
  30.  
  31.   { EXEC.PAS version 1.3
  32.  
  33.   This program contains two functions that allow you to run other
  34.   programs from within a Turbo Pascal program. The first function,
  35.   SubProcess, actually calls a different program using MS-DOS call
  36.   4BH, EXEC. The second function, GetComSpec, returns the path name
  37.   of the command interpreter, which is necessary to do certain
  38.   operations. There is also a main program that allows you to test
  39.   the functions.
  40.  
  41.   }
  42.   Program Exec;
  43.   Type
  44.     Str66=String[66];
  45.     Str255=String[255];
  46.  
  47.   Function SubProcess(CommandLine: Str255): Integer;
  48.     { Pass this function a string of the form
  49.         'D:\FULL\PATH\NAME\OF\FILE.TYP parameter1 parameter2 ...'
  50.  
  51.       For example,
  52.         'C:\SYSTEM\CHKDSK.COM'
  53.         'A:\WS.COM DOCUMENT.1'
  54.         'C:\DOS\LINK.EXE TEST;'
  55.         'C:\COMMAND.COM /C COPY *.* B:\BACKUP >FILESCOP.IED'
  56.  
  57.  
  58.   The third example shows several things. To do any of the
  59.   following, you must invoke the command processor and let it do
  60.   the work: redirection; piping; path searching; searching for the
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  76.   VERSION : ALL
  77.        OS : PC-DOS, MS-DOS
  78.      DATE : August 1, 1986                               PAGE : 2/5
  79.     TITLE : EXECUTE SUBPROCESS CALL
  80.  
  81.  
  82.  
  83.  
  84.   extension of a program (.COM, .EXE, or .BAT); batch files; and
  85.   internal DOS commands. The name of the command processor file is
  86.   stored in the DOS environment. The function GetComSpec in this
  87.   file returns the path name of the command processor. Also note
  88.   that you must use the /C parameter or COMMAND will not work
  89.   correctly. You can also call COMMAND with no parameters. This
  90.   will allow the user to use the DOS prompt to run anything (as
  91.   long as there is enough memory). To get back to your program,  he
  92.   can type the command EXIT.
  93.  
  94.   Actual example:
  95.     I:=SubProcess(GetComSpec+' /C COPY *.* B:\BACKUP
  96.   >FILESCOP.IED');
  97.  
  98.   The value returned is the result returned by DOS after the EXEC
  99.   call. The most common values are:
  100.  
  101.        0: Success
  102.        1: Invalid function (should never happen with this routine)
  103.        2: File/path not found
  104.        8: Not enough memory to load program
  105.       10: Bad environment (greater than 32K)
  106.       11: Illegal .EXE file format
  107.  
  108.   If you get any other result, consult an MS-DOS Technical
  109.   Reference manual.
  110.  
  111.   VERY IMPORTANT NOTE: you MUST use the Options menu of Turbo
  112.   Pascal to restrict the amount of free dynamic memory used by your
  113.   program. Only the memory that is not used by the heap is
  114.   available for use by other programs. }
  115.  
  116.     Const
  117.       SSSave: Integer=0;
  118.       SPSave: Integer=0;
  119.  
  120.     Var
  121.       Regs: Record Case Integer Of
  122.               1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
  123.               2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
  124.             End;
  125.       FCB1,FCB2: Array [0..36] Of Byte;
  126.       PathName: Str66;
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  142.   VERSION : ALL
  143.        OS : PC-DOS, MS-DOS
  144.      DATE : August 1, 1986                               PAGE : 3/5
  145.     TITLE : EXECUTE SUBPROCESS CALL
  146.  
  147.  
  148.  
  149.  
  150.       CommandTail: Str255;
  151.       ParmTable: Record
  152.                    EnvSeg: Integer;
  153.                    ComLin: ^Integer;
  154.                    FCB1Pr: ^Integer;
  155.                    FCB2Pr: ^Integer;
  156.                  End;
  157.       I,RegsFlags: Integer;
  158.  
  159.     Begin
  160.       If Pos(' ',CommandLine)=0 Then
  161.        Begin
  162.         PathName:=CommandLine+#0;
  163.         CommandTail:=^M;
  164.        End
  165.       Else
  166.        Begin
  167.         PathName:=Copy(CommandLine,1,Pos(' ',CommandLine)-1)+#0;
  168.         CommandTail:=Copy(CommandLine,Pos(' ',CommandLine),255)+^M;
  169.        End;
  170.       CommandTail[0]:=Pred(CommandTail[0]);
  171.       With Regs Do
  172.        Begin
  173.         FillChar(FCB1,Sizeof(FCB1),0);
  174.         AX:=$2901;
  175.         DS:=Seg(CommandTail[1]);
  176.         SI:=Ofs(CommandTail[1]);
  177.         ES:=Seg(FCB1);
  178.         DI:=Ofs(FCB1);
  179.         MsDos(Regs); { Create FCB 1 }
  180.         FillChar(FCB2,Sizeof(FCB2),0);
  181.         AX:=$2901;
  182.         ES:=Seg(FCB2);
  183.         DI:=Ofs(FCB2);
  184.         MsDos(Regs); { Create FCB 2 }
  185.         ES:=CSeg;
  186.         BX:=SSeg-CSeg+MemW[CSeg:MemW[CSeg:$0101]+$112];
  187.         AH:=$4A;
  188.         MsDos(Regs); { Deallocate unused memory }
  189.         With ParmTable Do
  190.          Begin
  191.           EnvSeg:=MemW[CSeg:$002C];
  192.           ComLin:=Addr(CommandTail);
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  208.   VERSION : ALL
  209.        OS : PC-DOS, MS-DOS
  210.      DATE : August 1, 1986                               PAGE : 4/5
  211.     TITLE : EXECUTE SUBPROCESS CALL
  212.  
  213.  
  214.  
  215.  
  216.           FCB1Pr:=Addr(FCB1);
  217.           FCB2Pr:=Addr(FCB2);
  218.          End;
  219.  
  220.      InLine($8D/$96/ PathName /$42/  { <DX>:=Ofs(PathName[1]); }
  221.             $8D/$9E/ ParmTable /     { <BX>:=Ofs(ParmTable);   }
  222.             $B8/$00/$4B/             { <AX>:=$4B00;            }
  223.             $1E/$55/                 { Save <DS>, <BP>         }
  224.             $16/$1F/                 { <DS>:=Seg(PathName[1]); }
  225.             $16/$07/                 { <ES>:=Seg(ParmTable);   }
  226.             $2E/$8C/$16/ SSSave /    { Save <SS> in SSSave     }
  227.             $2E/$89/$26/ SPSave /    { Save <SP> in SPSave     }
  228.             $FA/                     { Disable interrupts      }
  229.             $CD/$21/                 { Call MS-DOS             }
  230.             $FA/                     { Disable interrupts      }
  231.             $2E/$8B/$26/ SPSave /    { Restore <SP>            }
  232.             $2E/$8E/$16/ SSSave /    { Restore <SS>            }
  233.             $FB/                     { Enable interrupts       }
  234.             $5D/$1F/                 { Restore <BP>,<DS>       }
  235.             $9C/$8F/$86/ RegsFlags / { Flags:=<CPU flags>      }
  236.             $89/$86/ Regs );         { Regs.AX:=<AX>;          }
  237.  
  238.   { The manipulation of SS and SP is necessary because  under DOS
  239.   2.x, after returning from an EXEC call, ALL  registers are
  240.   destroyed except CS and IP! }
  241.  
  242.         If (RegsFlags And 1)<>0 Then SubProcess:=AX
  243.         Else SubProcess:=0;
  244.        End;
  245.     End;
  246.  
  247.   Function GetComSpec: Str66;
  248.     Type
  249.       Env=Array [0..32767] Of Char;
  250.     Var
  251.       EPtr: ^Env;
  252.       EStr: Str255;
  253.       Done: Boolean;
  254.       I: Integer;
  255.  
  256.     Begin
  257.       EPtr:=Ptr(MemW[CSeg:$002C],0);
  258.       I:=0;
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  274.   VERSION : ALL
  275.        OS : PC-DOS, MS-DOS
  276.      DATE : August 1, 1986                               PAGE : 5/5
  277.     TITLE : EXECUTE SUBPROCESS CALL
  278.  
  279.  
  280.  
  281.  
  282.       Done:=False;
  283.       EStr:='';
  284.       Repeat
  285.         If EPtr^[I]=#0 Then
  286.          Begin
  287.           If EPtr^[I+1]=#0 Then Done:=True;
  288.           If Copy(EStr,1,8)='COMSPEC=' Then
  289.            Begin
  290.             GetComSpec:=Copy(EStr,9,100);
  291.             Done:=True;
  292.            End;
  293.           EStr:='';
  294.          End
  295.         Else EStr:=EStr+EPtr^[I];
  296.         I:=I+1;
  297.       Until Done;
  298.     End;
  299.  
  300.   { Example program. Set both mInimum and mAximum free dynamic
  301.   memory to 100 and compile this to a .COM file. Delete the  next
  302.   line to enable: }
  303.  
  304.   Var Command: Str255;
  305.       I: Integer;
  306.  
  307.   Begin
  308.     Write('Enter a * to quit; put a * before a ');
  309.     Writeln('command to use COMMAND.COM.');
  310.     Repeat
  311.       Write('=->');
  312.       ReadLn(Command);
  313.       If Command='*' Then Halt;
  314.       If Command<>'' Then
  315.        Begin
  316.         If Command[1]='*' Then
  317.            Command:=GetComSpec+' /C '+Copy(Command,2,255);
  318.         I:=SubProcess(Command);
  319.         If I<>0 Then WriteLn('Error - ',I);
  320.        End;
  321.     Until False;
  322.   End.
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.